package com.harmony.pilot.completion.controller;

import com.harmony.pilot.common.dto.CodeContext;
import com.harmony.pilot.common.dto.Location;
import com.harmony.pilot.common.dto.RestResult;
import com.harmony.pilot.completion.service.NavigationService;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 代码导航控制器
 */
@Slf4j
@RestController
@RequestMapping("/completion/navigation")
@RequiredArgsConstructor
public class NavigationController {
    
    private final NavigationService navigationService;
    
    /**
     * 跳转到定义
     */
    @PostMapping("/definition")
    public RestResult<Location> goToDefinition(@RequestBody NavigationRequest request) {
        log.info("Finding definition for: {} in {}", request.getSymbol(), request.getFilePath());
        
        try {
            CodeContext context = buildContext(request);
            Location location = navigationService.goToDefinition(request.getSymbol(), context);
            
            if (location == null) {
                return RestResult.error("Definition not found for: " + request.getSymbol());
            }
            
            return RestResult.success(location);
        } catch (Exception e) {
            log.error("Failed to find definition", e);
            return RestResult.error("Failed to find definition: " + e.getMessage());
        }
    }
    
    /**
     * 查找所有引用
     */
    @PostMapping("/references")
    public RestResult<List<Location>> findReferences(@RequestBody NavigationRequest request) {
        log.info("Finding references for: {}", request.getSymbol());
        
        try {
            CodeContext context = buildContext(request);
            List<Location> references = navigationService.findReferences(
                request.getSymbol(), context);
            
            return RestResult.success(references);
        } catch (Exception e) {
            log.error("Failed to find references", e);
            return RestResult.error("Failed to find references: " + e.getMessage());
        }
    }
    
    /**
     * 查找实现
     */
    @PostMapping("/implementations")
    public RestResult<List<Location>> findImplementations(@RequestBody NavigationRequest request) {
        log.info("Finding implementations for: {}", request.getSymbol());
        
        try {
            CodeContext context = buildContext(request);
            List<Location> implementations = navigationService.findImplementations(
                request.getSymbol(), context);
            
            return RestResult.success(implementations);
        } catch (Exception e) {
            log.error("Failed to find implementations", e);
            return RestResult.error("Failed to find implementations: " + e.getMessage());
        }
    }
    
    /**
     * 符号搜索
     */
    @PostMapping("/search")
    public RestResult<List<NavigationService.SymbolInfo>> searchSymbols(
            @RequestBody SymbolSearchRequest request) {
        
        log.info("Searching symbols: {}", request.getQuery());
        
        try {
            List<NavigationService.SymbolInfo> symbols = navigationService.searchSymbols(
                request.getQuery(),
                request.getProjectRoot(),
                request.getMaxResults() != null ? request.getMaxResults() : 50
            );
            
            return RestResult.success(symbols);
        } catch (Exception e) {
            log.error("Failed to search symbols", e);
            return RestResult.error("Failed to search symbols: " + e.getMessage());
        }
    }
    
    private CodeContext buildContext(NavigationRequest request) {
        CodeContext context = new CodeContext();
        context.setFilePath(request.getFilePath());
        context.setProjectRoot(request.getProjectRoot());
        context.setCode(request.getCode());
        context.setCursorLine(request.getLine());
        context.setCursorColumn(request.getColumn());
        return context;
    }
    
    @Data
    public static class NavigationRequest {
        private String symbol;
        private String filePath;
        private String projectRoot;
        private String code;
        private Integer line;
        private Integer column;
    }
    
    @Data
    public static class SymbolSearchRequest {
        private String query;
        private String projectRoot;
        private Integer maxResults;
    }
}

